<template>
  <div class="page-container">
    <div class="page-header">
      <h2>实验上交情况统计</h2>
    </div>
    
    <!-- 条件选择 -->
    <div class="operation-container">
      <el-form :model="form" label-width="100px" inline>
        <el-form-item label="班级">
          <el-select v-model="form.classId" placeholder="请选择班级" style="width: 220px;">
            <el-option
              v-for="item in classList"
              :key="item.id"
              :label="item.name"
              :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="课程">
          <el-select v-model="form.courseId" placeholder="请选择课程" style="width: 220px;">
            <el-option
              v-for="item in courseList"
              :key="item.id"
              :label="item.name"
              :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="实验报告目录">
          <el-input v-model="form.reportFolderPath" placeholder="实验报告文件夹路径" style="width: 320px;"></el-input>
          <el-button type="primary" @click="openFolderDialog" style="margin-left: 10px;">浏览</el-button>
        </el-form-item>
      </el-form>
      
      <div style="margin-top: 15px;">
        <el-button type="primary" @click="startStatistics" :disabled="!canStartStatistics">开始统计</el-button>
        <el-button type="success" @click="exportToExcel" :disabled="!hasStatisticsResult">导出Excel</el-button>
      </div>
    </div>
    
    <!-- 统计结果展示 -->
    <div v-if="hasStatisticsResult">
      <!-- 选项卡 -->
      <el-tabs v-model="activeTab">
        <el-tab-pane label="学生维度统计" name="student">
          <div class="table-container">
            <el-table :data="studentStatsList" border style="width: 100%">
              <el-table-column prop="studentId" label="学号" width="120"></el-table-column>
              <el-table-column prop="name" label="姓名" width="100"></el-table-column>
              <el-table-column prop="missingCount" label="缺交数量" width="100"></el-table-column>
              <el-table-column prop="missingExperiments" label="缺交实验列表">
                <template #default="scope">
                  <el-tag 
                    v-for="exp in scope.row.missingExperiments" 
                    :key="exp" 
                    type="danger"
                    style="margin-right: 5px; margin-bottom: 5px;">
                    {{ exp }}
                  </el-tag>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </el-tab-pane>
        
        <el-tab-pane label="实验维度统计" name="experiment">
          <div class="table-container">
            <el-table :data="experimentStatsList" border style="width: 100%">
              <el-table-column prop="experimentName" label="实验名称" width="120"></el-table-column>
              <el-table-column prop="missingCount" label="缺交人数" width="100"></el-table-column>
              <el-table-column prop="submitRate" label="提交率" width="120">
                <template #default="scope">
                  {{ (scope.row.submitRate * 100).toFixed(2) }}%
                </template>
              </el-table-column>
              <el-table-column prop="missingStudents" label="缺交学生列表">
                <template #default="scope">
                  <el-tag 
                    v-for="student in scope.row.missingStudents" 
                    :key="student.id" 
                    type="danger"
                    style="margin-right: 5px; margin-bottom: 5px;">
                    {{ student.name }}
                  </el-tag>
                </template>
              </el-table-column>
            </el-table>
          </div>
          
          <!-- 可视化图表 -->
          <div class="chart-container" ref="chartRef"></div>
        </el-tab-pane>
      </el-tabs>
    </div>
    <input
      type="file"
      ref="folderInput"
      webkitdirectory
      directory
      multiple
      style="display: none"
      @change="handleFolderChange" />
  </div>
</template>

<script>
import { ref, reactive, computed, watch, nextTick, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import * as XLSX from 'xlsx'
import * as echarts from 'echarts'
import { saveAs } from 'file-saver'
import { classApi, courseApi, statisticsApi } from '../utils/api'

/* eslint-disable no-unused-vars */
// 组合模式 - 统计数据组织
class StatisticsComponent {
  constructor(name) {
    this.name = name
  }

  add() {
    throw new Error('抽象方法，需要子类实现')
  }

  remove() {
    throw new Error('抽象方法，需要子类实现')
  }

  getStatistics() {
    throw new Error('抽象方法，需要子类实现')
  }
}

// 统计组合类 - 课程统计（复合组件）
class CourseStatistics extends StatisticsComponent {
  constructor(name, courseId) {
    super(name)
    this.courseId = courseId
    this.children = []
  }
  
  add(component) {
    this.children.push(component)
  }
  
  remove(component) {
    const index = this.children.findIndex(child => child === component)
    if (index !== -1) {
      this.children.splice(index, 1)
    }
  }
  
  getStatistics() {
    return {
      name: this.name,
      id: this.courseId,
      children: this.children.map(child => child.getStatistics())
    }
  }
}

// 统计叶子类 - 实验统计（叶子组件）
class ExperimentStatistics extends StatisticsComponent {
  constructor(name, experimentId, missingStudents, totalStudents) {
    super(name)
    this.experimentId = experimentId
    this.missingStudents = missingStudents
    this.totalStudents = totalStudents
  }
  
  add() {
    throw new Error('叶子节点不能添加子节点')
  }
  
  remove() {
    throw new Error('叶子节点不能移除子节点')
  }
  
  getStatistics() {
    return {
      experimentName: this.name,
      experimentId: this.experimentId,
      missingCount: this.missingStudents.length,
      submitRate: (this.totalStudents - this.missingStudents.length) / this.totalStudents,
      missingStudents: this.missingStudents
    }
  }
}
/* eslint-enable no-unused-vars */

// 策略模式 - 导出策略
class ExportStrategy {
  // eslint-disable-next-line no-unused-vars
  export(data, filename) {
    throw new Error('抽象方法，需要子类实现')
  }
}

// Excel导出策略
class ExcelExportStrategy extends ExportStrategy {
  export(data, filename) {
    const wb = XLSX.utils.book_new()
    
    // 学生维度统计表
    const studentData = data.studentStats.map(student => ({
      '学号': student.studentId,
      '姓名': student.name,
      '缺交数量': student.missingCount,
      '缺交实验列表': student.missingExperiments.join(', ')
    }))
    
    const studentWs = XLSX.utils.json_to_sheet(studentData)
    XLSX.utils.book_append_sheet(wb, studentWs, '学生维度统计')
    
    // 实验维度统计表
    const experimentData = data.experimentStats.map(exp => ({
      '实验名称': exp.experimentName,
      '缺交人数': exp.missingCount,
      '提交率': (exp.submitRate * 100).toFixed(2) + '%',
      '缺交学生列表': exp.missingStudents.map(s => s.name).join(', ')
    }))
    
    const experimentWs = XLSX.utils.json_to_sheet(experimentData)
    XLSX.utils.book_append_sheet(wb, experimentWs, '实验维度统计')
    
    // 导出Excel文件
    const excelBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' })
    const blob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
    saveAs(blob, `${filename}.xlsx`)
  }
}

// 导出上下文
class ExportContext {
  constructor(strategy) {
    this.strategy = strategy
  }
  
  setStrategy(strategy) {
    this.strategy = strategy
  }
  
  executeExport(data, filename) {
    return this.strategy.export(data, filename)
  }
}

export default {
  name: 'StatisticsManagement',
  setup() {
    // 数据源
    const classList = ref([])
    const courseList = ref([])
    
    // 加载班级列表
    const loadClasses = async () => {
      try {
        const data = await classApi.getClasses()
        classList.value = data || []
      } catch (error) {
        ElMessage.error('获取班级列表失败')
        console.error(error)
      }
    }
    
    // 加载课程列表
    const loadCourses = async () => {
      try {
        const data = await courseApi.getCourses()
        courseList.value = data || []
      } catch (error) {
        ElMessage.error('获取课程列表失败')
        console.error(error)
      }
    }
    
    // 在组件挂载时加载数据
    onMounted(() => {
      loadClasses()
      loadCourses()
    })
    
    // 表单数据
    const form = reactive({
      classId: '',
      courseId: '',
      reportFolderPath: ''
    })
    
    // 计算属性 - 是否可以开始统计
    const canStartStatistics = computed(() => {
      return form.classId && form.courseId && form.reportFolderPath
    })
    
    // 打开文件夹选择对话框
    const openFolderDialog = () => {
      if (folderInput.value) {
        folderInput.value.click()
      }
    }
    
    // 处理文件夹变更
    const handleFolderChange = (event) => {
      const files = Array.from(event.target.files || [])
      if (files.length === 0) {
        return
      }
      selectedFiles.value = files
      // 获取文件夹根路径（webkitRelativePath 的第一段）
      const firstPath = files[0].webkitRelativePath
      const rootDir = firstPath.split('/')[0]
      form.reportFolderPath = rootDir
      ElMessage.success(`已选择文件夹：${rootDir}，共 ${files.length} 个文件`)
    }
    
    // 统计相关
    const hasStatisticsResult = ref(false)
    const activeTab = ref('student')
    const studentStatsList = ref([])
    const experimentStatsList = ref([])
    
    // 图表相关
    const chartRef = ref(null)
    let chart = null
    
    // 初始化图表
    const initChart = () => {
      if (chart) {
        chart.dispose()
      }
      
      nextTick(() => {
        if (chartRef.value) {
          chart = echarts.init(chartRef.value)
          updateChart()
        }
      })
    }
    
    // 更新图表数据
    const updateChart = () => {
      if (!chart || experimentStatsList.value.length === 0) return
      
      const xData = experimentStatsList.value.map(item => item.experimentName)
      const yData = experimentStatsList.value.map(item => item.submitRate * 100)
      
      const option = {
        title: {
          text: '实验提交率统计',
          left: 'center'
        },
        tooltip: {
          trigger: 'axis',
          formatter: '{b}: {c}%'
        },
        xAxis: {
          type: 'category',
          data: xData
        },
        yAxis: {
          type: 'value',
          min: 0,
          max: 100,
          axisLabel: {
            formatter: '{value}%'
          }
        },
        series: [
          {
            name: '提交率',
            type: 'line',
            data: yData,
            markLine: {
              data: [{ type: 'average', name: '平均值' }]
            }
          }
        ]
      }
      
      chart.setOption(option)
    }
    
    // 监听窗口大小变化，调整图表大小
    window.addEventListener('resize', () => {
      if (chart) {
        chart.resize()
      }
    })
    
    // 使用API统计实验报告提交情况
    const startStatistics = async () => {
      if (!canStartStatistics.value) {
        ElMessage.warning('请完善统计条件')
        return
      }
      
      try {
        const params = {
          classId: form.classId,
          courseId: form.courseId,
          reportFolderPath: form.reportFolderPath
        }
        
        // 调用后端API进行统计
        const result = await statisticsApi.analyzeSubmissions(params)
        
        if (result) {
          // 解析返回的统计结果
          studentStatsList.value = result.studentStatistics || []
          
          // 后端字段适配转换
          const rawExperimentStats = result.experimentStatistics || []
          const transformedExperimentStats = rawExperimentStats.map(exp => ({
            ...exp,
            // 后端字段 submissionRate -> 前端使用 submitRate
            submitRate: exp.submissionRate,
            // 将缺交学生字符串列表转换为对象，保持与之前模板一致
            missingStudents: (exp.missingStudents || []).map(nameStr => ({
              id: nameStr, // 字符串本身作为唯一键
              name: nameStr
            }))
          }))
          experimentStatsList.value = transformedExperimentStats
          
          // 显示统计结果
          hasStatisticsResult.value = true
          
          // 初始化图表
          initChart()
          
          ElMessage.success('统计完成')
        } else {
          ElMessage.warning('未获取到统计数据')
        }
      } catch (error) {
        console.error(error)
        ElMessage.error(`统计失败: ${error.message}`)
      }
    }
    
    // 导出Excel
    const exportToExcel = async () => {
      if (!hasStatisticsResult.value) {
        ElMessage.warning('请先进行统计')
        return
      }
      
      try {
        const params = {
          classId: form.classId,
          courseId: form.courseId,
          reportFolderPath: form.reportFolderPath
        }
        
        // 从API获取导出数据
        const blob = await statisticsApi.exportSubmissions(params)
        
        // 处理返回的二进制数据
        const selectedClass = classList.value.find(c => c.id === form.classId)
        const selectedCourse = courseList.value.find(c => c.id === form.courseId)
        const filename = `${selectedCourse.name}-${selectedClass.name}-实验报告统计.xlsx`
        
        // 使用file-saver直接保存blob
        saveAs(blob, filename)
        
        ElMessage.success('导出成功')
      } catch (error) {
        console.error(error)
        ElMessage.error(`导出失败: ${error.message}`)
        
        // 如果API调用失败，使用本地导出作为备选方案
        try {
          const selectedClass = classList.value.find(c => c.id === form.classId)
          const selectedCourse = courseList.value.find(c => c.id === form.courseId)
          
          const filename = `${selectedCourse.name}-${selectedClass.name}-实验报告统计`
          
          // 使用策略模式导出不同格式
          const excelStrategy = new ExcelExportStrategy()
          const exportContext = new ExportContext(excelStrategy)
          
          const data = {
            studentStats: studentStatsList.value,
            experimentStats: experimentStatsList.value
          }
          
          exportContext.executeExport(data, filename)
          
          ElMessage.success('使用本地数据导出成功')
        } catch (backupError) {
          console.error(backupError)
          ElMessage.error(`本地导出也失败: ${backupError.message}`)
        }
      }
    }
    
    // 监听activeTab变化，更新图表
    watch(activeTab, (newVal) => {
      if (newVal === 'experiment') {
        nextTick(() => {
          initChart()
        })
      }
    })
    
    const folderInput = ref(null)
    const selectedFiles = ref([])
    
    return {
      // 数据源
      classList,
      courseList,
      
      // 表单数据
      form,
      canStartStatistics,
      openFolderDialog,
      handleFolderChange,
      
      // 统计相关
      hasStatisticsResult,
      activeTab,
      studentStatsList,
      experimentStatsList,
      startStatistics,
      
      // 图表相关
      chartRef,
      
      // 导出相关
      exportToExcel,
      
      folderInput,
      selectedFiles,
    }
  }
}
</script>

<style scoped>
.chart-container {
  margin-top: 20px;
  height: 400px;
  width: 100%;
}
</style> 